import datetime
import os
import random
import uuid

import jwt
from django.conf import settings
from django.core.cache import caches
from django.db.transaction import atomic
from django.http import JsonResponse
from django.shortcuts import redirect
from django.views.decorators.csrf import csrf_exempt
from rest_framework.decorators import api_view
from rest_framework.generics import CreateAPIView
from rest_framework.response import Response

from blog.settings import SECRET_KEY
from user.auths import LoginAuthentication
from user.models import User, LoginLog, Article
from user.serializers import ArticlePostSerializer
from user.utils import TEL_PATTERN, gen_mobile_code, send_sms_by_luosimao, get_ip_address


def index(request):
    """首页"""
    return redirect('/static/html/home.html')


@csrf_exempt
def upload(request):
    """上传图片"""
    data = []
    for image_file in request.FILES.values():
        if image_file:
            ext = os.path.splitext(image_file.name)[-1]
            filename = uuid.uuid1().hex + ext
            url = f'/media/images/{filename}'
            path = os.path.join(settings.MEDIA_ROOT, f'images/{filename}')
            with open(path, 'wb') as file_stream:
                file_stream.write(image_file.read())
            data.append(url)
    return JsonResponse({'errno': 0, 'data': data})


@api_view(('POST', ))
def login(request):
    """登录（获取用户身份令牌）"""
    tel = request.data.get('tel', '')
    code_from_user = request.data.get('code', '0')
    code_from_cache = caches['default'].get(f'{tel}:check', '1')
    if code_from_user == code_from_cache:
        user = User.objects.filter(tel=tel).first()
        if user:
            payload = {
                'exp': datetime.datetime.utcnow() + datetime.timedelta(days=7),
                'data': {
                    'userid': user.userid,
                    'locked': user.locked
                }
            }
            token = jwt.encode(payload, SECRET_KEY, algorithm='HS256').decode()
            with atomic():
                user.credit += random.randint(1, 5)
                user.save()
                loginlog = LoginLog()
                loginlog.userid = user.userid
                loginlog.ipaddr = get_ip_address(request)
                loginlog.save()
            data = {
                'code': 10000,
                'token': token,
                'userid': user.userid,
                'nickname': user.nickname
            }
        else:
            data = {'code': 10002, 'message': '该手机号尚未注册'}
    else:
        data = {'code': 10001, 'message': '无效的手机验证码'}
    return Response(data)


@api_view(('GET', ))
def send_code_by_sms(request, tel):
    """发送短信验证码"""
    if TEL_PATTERN.fullmatch(tel):
        if caches['default'].get(f'{tel}:block'):
            data = {'code': 20001, 'message': '请不要在120秒以内重复发送手机验证码'}
        else:
            code = gen_mobile_code()
            message = f'您的短信验证码是{code}，打死也不能告诉别人哟！【Python小课】'
            send_sms_by_luosimao(tel, message=message)
            caches['default'].set(f'{tel}:block', code, timeout=120)
            caches['default'].set(f'{tel}:check', code, timeout=300)
            data = {'code': 20000, 'message': '短信验证码发送成功'}
    else:
        data = {'code': 20002, 'message': '请提供有效的手机号'}
    return Response(data)


class ArticleView(CreateAPIView):
    """文章视图"""
    queryset = Article.objects.all()
    serializer_class = ArticlePostSerializer
    authentication_classes = (LoginAuthentication, )
